package cn.lili.controller.passport;

import cn.lili.common.aop.annotation.DemoSite;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.security.token.Token;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.common.vo.SearchVO;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.permission.entity.dos.AdminUser;
import cn.lili.modules.permission.entity.dos.Role;
import cn.lili.modules.permission.entity.dto.AdminUserDTO;
import cn.lili.modules.permission.entity.vo.AdminUserVO;
import cn.lili.modules.permission.service.AdminUserService;
import cn.lili.modules.permission.service.DepartmentService;
import cn.lili.modules.system.aspect.annotation.SystemLogPoint;
import cn.lili.modules.verification.entity.enums.VerificationEnums;
import cn.lili.modules.verification.service.VerificationService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 管理员接口
 *
 * @author Chopper
 * @since 2020/11/16 10:57
 */
@Slf4j
@RestController
@Api(tags = "管理员")
@RequestMapping("/manager/user")
@Transactional(rollbackFor = Exception.class)
@Validated
public class AdminUserManagerController {
	@Autowired
	private AdminUserService adminUserService;
	@Autowired
	private DepartmentService departmentService;
	/**
	 * 会员
	 */
	@Autowired
	private MemberService memberService;

	@Autowired
	private VerificationService verificationService;

	@RequestMapping(value = "/login")
	@ApiOperation(value = "登录管理员")
	@SystemLogPoint(description = "管理员登录", customerLog = "'管理员登录请求:'+#username", type = "1", parameter = true)
	public ResultMessage<Token> login(@NotNull(message = "用户名不能为空") @RequestParam String username,
			@NotNull(message = "密码不能为空") @RequestParam String password, @RequestHeader String uuid) {
		if (verificationService.check(uuid, VerificationEnums.LOGIN)) {
			return ResultUtil.data(adminUserService.login(username, password));
		} else {
			throw new ServiceException(ResultCode.VERIFICATION_ERROR);
		}
	}

	@ApiOperation(value = "注销接口")
	@RequestMapping("/logout")
	@SystemLogPoint(description = "退出登录", customerLog = "退出登录请求", type = "1")
	public ResultMessage<Object> logout() {
		this.memberService.logout(UserEnums.MANAGER);
		return ResultUtil.success();
	}

	@ApiOperation(value = "刷新token")
	@RequestMapping("/refresh/{refreshToken}")
	public ResultMessage<Object> refreshToken(@NotNull(message = "刷新token不能为空") @PathVariable String refreshToken) {
		return ResultUtil.data(this.adminUserService.refreshToken(refreshToken));
	}

	@RequestMapping(value = "/info")
	@ApiOperation(value = "获取当前登录用户接口")
	public ResultMessage<AdminUserVO> getUserInfo() {
		AuthUser tokenUser = UserContext.getCurrentUser();
		if (tokenUser != null) {
			AdminUserVO adminUser = new AdminUserVO(adminUserService.findByUsername(tokenUser.getUsername()));
			if (StringUtils.isNotEmpty(adminUser.getDepartmentId())) {
				adminUser.setDepartmentTitle(departmentService.getById(adminUser.getDepartmentId()).getTitle());
			}
			adminUser.setPassword(null);

			List<Role> roleList = adminUserService.findRoleById(adminUser.getId());
			adminUser.setRoles(roleList);
			return ResultUtil.data(adminUser);
		}
		throw new ServiceException(ResultCode.USER_NOT_LOGIN);
	}

	@PutMapping(value = "/edit")
	@ApiOperation(value = "修改用户自己资料", notes = "用户名密码不会修改")
	@SystemLogPoint(description = "修改自己资料", customerLog = "修改自己资料请求", type = "1")
	public ResultMessage<Object> editOwner(AdminUser adminUser) {

		AuthUser tokenUser = UserContext.getCurrentUser();
		if (tokenUser != null) {
			// 查询当前管理员
			AdminUser oldAdminUser = adminUserService.findByUsername(tokenUser.getUsername());
			oldAdminUser.setAvatar(adminUser.getAvatar());
			oldAdminUser.setNickName(adminUser.getNickName());
			if (!adminUserService.updateById(oldAdminUser)) {
				throw new ServiceException(ResultCode.USER_EDIT_ERROR);
			}
			return ResultUtil.success(ResultCode.USER_EDIT_SUCCESS);
		}
		throw new ServiceException(ResultCode.USER_NOT_LOGIN);
	}

	@PutMapping(value = "/admin/edit")
	@ApiOperation(value = "超级管理员修改其他管理员资料")
	@SystemLogPoint(description = "超级管理员修改其他管理员资料", customerLog = "超级管理员修改其他管理员资料请求", type = "1")
	@DemoSite
	public ResultMessage<Object> edit(@Valid AdminUser adminUser, @RequestParam(required = false) List<String> roles) {
		if (!adminUserService.updateAdminUser(adminUser, roles)) {
			throw new ServiceException(ResultCode.USER_EDIT_ERROR);
		}
		return ResultUtil.success(ResultCode.USER_EDIT_SUCCESS);
	}

	/**
	 * 修改密码
	 *
	 * @param password
	 * @param newPassword
	 * @return
	 */
	@PutMapping(value = "/editPassword")
	@ApiOperation(value = "修改密码")
	@SystemLogPoint(description = "修改密码", customerLog = "修改密码请求", type = "1")
	@DemoSite
	public ResultMessage<Object> editPassword(String password, String newPassword) {
		adminUserService.editPassword(password, newPassword);
		return ResultUtil.success(ResultCode.USER_EDIT_SUCCESS);
	}

	@RequestMapping(value = "/resetPassword/{ids}")
	@ApiOperation(value = "重置密码")
	@SystemLogPoint(description = "重置密码", customerLog = "重置密码请求", type = "1")
	@DemoSite
	public ResultMessage<Object> resetPassword(@PathVariable List ids) {
		adminUserService.resetPassword(ids);
		return ResultUtil.success(ResultCode.USER_EDIT_SUCCESS);
	}

	@GetMapping
	@ApiOperation(value = "多条件分页获取用户列表")
	public ResultMessage<IPage<AdminUserVO>> getByCondition(AdminUserDTO user, SearchVO searchVo, PageVO pageVo) {
		IPage<AdminUserVO> page = adminUserService.adminUserPage(PageUtil.initPage(pageVo),
				PageUtil.initWrapper(user, searchVo));

		return ResultUtil.data(page);
	}

	@PostMapping
	@ApiOperation(value = "添加用户")
	@SystemLogPoint(description = "添加用户", customerLog = "添加用户请求", type = "1")
	public ResultMessage<Object> register(@Valid AdminUserDTO adminUser,
			@RequestParam(required = false) List<String> roles) {
		int rolesMaxSize = 10;
		if (roles != null && roles.size() >= rolesMaxSize) {
			throw new ServiceException(ResultCode.PERMISSION_BEYOND_TEN);
		}
		// 判断用户名是否存在
		if (adminUserService.findByUsername(adminUser.getUsername()) != null) {
			throw new ServiceException(ResultCode.USER_NAME_EXIST);
		}
		// 判断手机号是否存在
		if (adminUserService.findByPhone(adminUser.getMobile()) != null) {
			throw new ServiceException(ResultCode.USER_PHONE_EXIST);
		}
		// 代理商创建下级的时候自动将本级资料带过去
		AuthUser tokenUser = UserContext.getCurrentUser();
		AdminUser byId = adminUserService.getById(tokenUser.getId());
		if (StringUtils.isNotEmpty(byId.getMemberId())) { // memberId
			adminUser.setMemberId(byId.getMemberId());
		}
		if (StringUtils.isNotEmpty(byId.getPromotionCode())) { // 推广码
			adminUser.setPromotionCode(byId.getPromotionCode());
		}
		if (StringUtils.isNotEmpty(byId.getRegionId())) { // 代理区域id
			adminUser.setRegionId(byId.getRegionId());
		}
		if (StringUtils.isNotEmpty(byId.getRegion())) { // 代理区域id
			adminUser.setRegion(byId.getRegion());
		}
		adminUserService.saveAdminUser(adminUser, roles);
		return ResultUtil.success();
	}

	@PutMapping(value = "/enable/{userId}")
	@ApiOperation(value = "禁/启 用 用户")
	@SystemLogPoint(description = "禁/启用用户", customerLog = "禁/启用用户请求", type = "1")
	@DemoSite
	public ResultMessage<Object> disable(@ApiParam("用户唯一id标识") @PathVariable String userId, Boolean status) {
		AdminUser user = adminUserService.getById(userId);
		if (user == null) {
			throw new ServiceException(ResultCode.USER_NOT_EXIST);
		}
		user.setStatus(status);
		adminUserService.updateById(user);
		return ResultUtil.success();
	}

	@DeleteMapping(value = "/{ids}")
	@ApiOperation(value = "批量通过ids删除")
	@SystemLogPoint(description = "删除用户", customerLog = "删除用户请求", type = "1")
	@DemoSite
	public ResultMessage<Object> delAllByIds(@PathVariable List<String> ids) {
		adminUserService.deleteCompletely(ids);
		return ResultUtil.success();
	}

}
